package com.yhn.bubblevideo.admin.service.impl;


import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhn.bubblevideo.admin.mapper.CategoryMapper;
import com.yhn.bubblevideo.admin.service.CategoryService;
import com.yhn.bubblevideo.common.enums.BaseErrorCode;
import com.yhn.bubblevideo.common.exception.BusinessException;
import com.yhn.bubblevideo.common.exception.ThrowUtils;
import com.yhn.bubblevideo.model.domain.Category;
import com.yhn.bubblevideo.model.dto.req.category.CategoryAddRequestDTO;
import com.yhn.bubblevideo.model.dto.req.category.CategoryEditRequestDTO;
import com.yhn.bubblevideo.model.dto.req.category.CategoryQueryRequestDTO;
import com.yhn.bubblevideo.model.dto.req.common.DeleteRequest;
import com.yhn.bubblevideo.model.dto.resp.CategoryRespDTO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.yhn.bubblevideo.common.constant.CommonConstant.MAX_PAGE_SIZE;

/**
 * @author 86177
 * @description 针对表【category】的数据库操作Service实现
 * @createDate 2024-12-02 12:49:57
 */
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    /**
     * 分页查询
     */
    @Override
    public Page<CategoryRespDTO> queryPage(CategoryQueryRequestDTO requestParam) {
        if (requestParam == null) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        long current = requestParam.getCurrent();
        long size = requestParam.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > MAX_PAGE_SIZE, BaseErrorCode.PARAMS_ERROR);
        Page<Category> categoryPage = this.page(new Page<>(current, size),
                this.getQueryWrapper());
        Page<CategoryRespDTO> categoryRespPage = new Page<>(current, size, categoryPage.getTotal());
        List<CategoryRespDTO> categoryVO = this.getCategoryVO(categoryPage.getRecords());
        categoryRespPage.setRecords(categoryVO);
        return categoryRespPage;
    }

    /**
     * 返回父级分类为0或NULL的查询条件
     */
    @Override
    public LambdaQueryWrapper<Category> getQueryWrapper() {
        return Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentCategoryId, 0)
                .or()
                .isNull(Category::getParentCategoryId);

    }

    /**
     * 获取脱敏对象集合
     *
     * @param categoryList 查询请求
     * @return 脱敏对象集合
     */
    @Override
    public List<CategoryRespDTO> getCategoryVO(List<Category> categoryList) {
        if (CollUtil.isEmpty(categoryList)) {
            return new ArrayList<>();
        }
        return categoryList.stream().map(this::getCategoryVO).collect(Collectors.toList());
    }


    /**
     * 将对象转化为脱敏对象
     *
     * @param category 原对象
     * @return 脱敏对象
     */
    @Override
    public CategoryRespDTO getCategoryVO(Category category) {
        if (category == null) {
            return null;
        }
        CategoryRespDTO categoryResp = new CategoryRespDTO();
        BeanUtils.copyProperties(category, categoryResp);
        return categoryResp;
    }

    /**
     * 根据ID获取信息
     *
     * @param id id
     * @return 实体信息
     */
    @Override
    public CategoryRespDTO getInfoById(Long id) {
        Category category = baseMapper.selectById(id);
        if (category == null) {
            throw new BusinessException(BaseErrorCode.NOT_FOUND_ERROR, "没有对应的信息");
        }
        return getCategoryVO(category);
    }

    /**
     * 保存信息
     *
     * @param requestParam 添加请求
     * @return 新生成的ID
     */
    @Override
    @Transactional
    public Long saveCategory(CategoryAddRequestDTO requestParam) {
        if (requestParam == null) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        LambdaQueryWrapper<Category> queryWrapper = Wrappers.lambdaQuery(Category.class)
                .eq(Category::getName, requestParam.getName());

        baseMapper.selectCount(queryWrapper);
        if (baseMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("该题目已存在");
        }
        Category category = new Category();
        BeanUtils.copyProperties(requestParam, category);
        boolean result = this.save(category);
        ThrowUtils.throwIf(!result, BaseErrorCode.OPERATION_ERROR);
        return category.getId();
    }


    /**
     * 修改信息
     *
     * @param requestParam 修改请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean updateCategory(CategoryEditRequestDTO requestParam) {
        if (requestParam == null || requestParam.getId() <= 0) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        Category category = new Category();
        BeanUtils.copyProperties(requestParam, category);
        long id = requestParam.getId();
        // 判断是否存在
        Category oldCategory = this.getById(id);
        ThrowUtils.throwIf(oldCategory == null, BaseErrorCode.NOT_FOUND_ERROR);
        boolean result = this.updateById(category);
        ThrowUtils.throwIf(!result, BaseErrorCode.OPERATION_ERROR);
        return true;
    }

    /**
     * 删除信息
     *
     * @param deleteRequest 删除请求
     * @return 是否修改成功
     */
    @Override
    @Transactional
    public Boolean deleteById(DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(BaseErrorCode.PARAMS_ERROR);
        }
        long id = deleteRequest.getId();
        // 判断是否存在
        // 先删除本身
        boolean b = this.removeById(id);
        //再删除其二级分类
        LambdaQueryWrapper<Category> queryWrapper = Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentCategoryId, id);
        this.remove(queryWrapper);
        ThrowUtils.throwIf(!b, BaseErrorCode.NOT_FOUND_ERROR);
        return true;
    }


    @Override
    public List<CategoryRespDTO> getChildCategory(Long parentCategoryId) {
        LambdaQueryWrapper<Category> queryWrapper = Wrappers.lambdaQuery(Category.class)
                .eq(Category::getParentCategoryId, parentCategoryId);
        return this.getCategoryVO(this.list(queryWrapper));
    }


}




